<?php
/** @noinspection PhpUnused */
declare(strict_types=1);

namespace app\shop\controller;

use app\shop\events\wxMsgPush\MiniappOrderSettlement;
use app\shop\library\ShopHelper;
use app\shop\library\ShopLogHelper;
use EasyWeChat\Kernel\Exceptions\BadRequestException;
use EasyWeChat\Kernel\Exceptions\InvalidArgumentException;
use EasyWeChat\Kernel\Exceptions\RuntimeException;
use EasyWeChat\OfficialAccount\Application;
use Psr\Http\Message\ResponseInterface;
use ReflectionException;
use think\facade\Event;
use think\helper\Arr;
use Throwable;

class WechatMessagePushController extends BaseController
{
    protected array $noNeedLogin = ['*'];

    public function addLog(string $message, mixed $data = ''): void
    {
        ShopLogHelper::info($message, $data);
    }

    /**
     * 推送事件类映射
     * @return string[]
     */
    public function eventsMapping(): array
    {
        return [
            'trade_manage_order_settlement' => MiniappOrderSettlement::class
        ];
    }

    /**
     * 微信小程序消息推送
     * @return ResponseInterface
     * @throws BadRequestException
     * @throws InvalidArgumentException
     * @throws RuntimeException
     * @throws ReflectionException
     * @throws Throwable
     */
    public function miniapp(): ResponseInterface
    {
        $this->addLog('接收到小程序消息推送', [
            'params' => request()->param()
        ]);

        $config = ShopHelper::get_setting_group('miniapp_group');
        $config = [
            'app_id'  => $config['miniapp_id'],
            'secret'  => $config['miniapp_secret'],
            'token'   => $config['miniapp_push_token'],
            'aes_key' => $config['miniapp_push_aes_key'],
        ];

        $app    = new Application($config);
        $server = $app->getServer();

        try {
            $message = $server->getDecryptedMessage();
            $this->addLog("解密数据：", $message);

            if (Arr::has($message, 'Event')) {
                $eventName  = $message['Event'];
                $eventClass = $this->eventsMapping()[$eventName] ?? '';
                $this->addLog('获取到事件名称：' . $eventName . '，映射的事件类：' . $eventClass);
                if ($eventClass) {
                    // 注册并触发事件处理
                    Event::listen($eventName, $eventClass);
                    Event::trigger($eventName, $message->toArray());
                }
            }
        } catch (Throwable $e) {
            $this->addLog("处理小程序消息推送异常", $e->getMessage());
        }

        return $server->serve();
    }
}